﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;

namespace BlackStar
{
    public delegate void KeyEvent(Keys k);

    public class KeyItemContentReader : ContentTypeReader<KeyItem>
    {
        protected override KeyItem Read(ContentReader input, KeyItem existingInstance)
        {
            KeyItem result = new KeyItem();
            result.Plain = input.ReadString();
            result.Shift = input.ReadString();
            return result;
        }
    }

    public class KeyItem
    {
        public string Plain;
        public string Shift;
    }

    public class Keyboard
    {
        protected Dictionary<Keys, KeyItem> keyMap;

        public event KeyEvent KeyDown;
        public event KeyEvent KeyUp;

        protected KeyboardState currentState;
        protected KeyboardState lastState;


        protected Keys[] lastKeys;
        protected Keys[] currentKeys;

        public Keyboard(ContentManager c, string keyMapFile)
        {
            keyMap = c.Load<Dictionary<Keys, KeyItem>>(keyMapFile);

            currentState = lastState = Microsoft.Xna.Framework.Input.Keyboard.GetState();

            lastKeys = currentKeys = new Keys[0];
        }

        public void Update()
        {
            lastState = currentState;
            currentState = Microsoft.Xna.Framework.Input.Keyboard.GetState();

            lastKeys = currentKeys;
            currentKeys = currentState.GetPressedKeys();

            foreach (Keys k in currentKeys)
            { if (!lastKeys.Contains<Keys>(k)) OnKeyDown(k); }

            foreach (Keys k in lastKeys)
            { if (!currentKeys.Contains<Keys>(k)) OnKeyUp(k); }
        }

        public bool IsKeyDown(Keys k)
        {
            return currentKeys.Contains<Keys>(k);
        }

        public bool Control
        {
            get
            {
                return currentKeys.Contains<Keys>(Keys.LeftControl) ||
                    currentKeys.Contains<Keys>(Keys.RightControl);
            }
        }

        public bool Shift
        {
            get
            {
                return currentKeys.Contains<Keys>(Keys.RightShift) ||
                    currentKeys.Contains<Keys>(Keys.LeftShift);
            }
        }

        protected void OnKeyDown(Keys k)
        { if (this.KeyDown != null) KeyDown(k); }

        protected void OnKeyUp(Keys k)
        { if (this.KeyUp != null) KeyUp(k); }

        public string GetChar(Keys k)
        {
            if (keyMap.ContainsKey(k))
            {
                if (Shift)
                { return keyMap[k].Shift.ToString(); }
                else
                { return keyMap[k].Plain.ToString(); }
            }
            else
            {
                return "";
            }
        }
    }
}
